G4: Edinaldo de Alencar / Igor Freire / Ramon Araújo / Ricardo Ribeiro
28 de outubro de 2014
Pacote utilizado para leitura em formato de séries temporais:
library(zoo)
Importar as bases de dados utilizando read.zoo:
# A base de dados e os scripts R estão no mesmo diretório (o diretório atual)
setwd(paste("~/Documents/Mestrado/UFPA/Mineração de Dados/data-mining-ppgee/trabalho-2-forecast/", sep=""))
# Inicialmente, ler a base de dados diários como um data frame (através de read.csv)
dataframe_diario <- read.csv(file = "dataset_diario.csv", sep = ";", dec = ",", header = TRUE)
# Em seguida, converter para uma série temporal (lista indexada pela data)
dataset_diario <- zoo(as.matrix(dataframe_diario[, -1:-2]), as.Date(dataframe_diario[,1], format = "%d/%m/%y"))
# Obs: em "format" usa-se y minusculo, pois a data está no formato dd/mm/yy
# A função read.zoo() abaixo não retorna lista com vetores categóricos e numéricos ao mesmo tempo.
# Isto é, se houver dados categóricos e numéricos na base, os numéricos serão convertidos.
# Por isso, a base com dados diários não foi lida diretamente com read.zoo. A base com dados mensais
# pode ser lida diretamente com read.zoo()
# Ler o .csv como uma série temporal (indexado pela data)
dataset_mensal <- read.zoo(file = "dataset_mensal.csv", sep = ";", dec = ",", header = TRUE,
index = 1, tz = "", FUN = as.yearmon, format = "%m/%Y", drop = FALSE)
# index -> coluna do arquivo .csv que contém a data
# Obs: em "format" usa-se Y maiúsculo, pois a data está no formato mm/yyyy
dataset_diario é a base com valores de fluxos diários de 2002 a 2009.dataset_mensal é a base com os valores de fluxo mensais de 1992 a 2009.sep =)dec =)Observar que a informação sobre os dias da semana é redundante, pois pode ser obtida através de:
dia <- weekdays(index(dataset_diario))
que tem como resultado, por exemplo, para as 10 primeiras amostras da base:
head(dia, 10)
## [1] "Terça Feira" "Quarta Feira" "Quinta Feira" "Sexta Feira"
## [5] "Sábado" "Domingo" "Segunda Feira" "Terça Feira"
## [9] "Quarta Feira" "Quinta Feira"
o qual pode ser confirmado comparando com as 10 primeiras entradas na coluna “dia” da base:
head(dataframe_diario[,2], 10)
## [1] ter qua qui sex sab dom seg ter qua qui
## Levels: dom qua qui sab seg sex ter
Por isso, na leitura da base em dataset_diario, esta coluna foi ignorada.
summary(dataset_diario)
## Index dataset_diario
## Min. :2002-01-01 Min. :11130
## 1st Qu.:2004-01-01 1st Qu.:19468
## Median :2005-12-31 Median :22811
## Mean :2005-12-31 Mean :23158
## 3rd Qu.:2007-12-31 3rd Qu.:26712
## Max. :2009-12-31 Max. :34292
summary(dataset_mensal)
## Index fluxo
## Min. :1992 Min. :261544
## 1st Qu.:1996 1st Qu.:408961
## Median :2001 Median :529912
## Mean :2001 Mean :548440
## 3rd Qu.:2005 3rd Qu.:662250
## Max. :2010 Max. :982708
Conversão dos dados para o formato de série temporal no R.
# Frequency --> numero de observações por unidade de tempo
# define a unidade de tempo (e.g. 12, unidade de tempo = ano)
tsMensal <- ts(dataset_mensal, frequency=12, start=1992)
plot(tsMensal, xlab="Anos", ylab="Fluxo")
Série temporal multi-sazonal
tsDiario <- msts(dataset_diario, seasonal.periods=c(7, 365.25), start=c(2002,1,1))
plot(tsDiario, xlab="Anos", ylab="Fluxo")
Decompor a série temporal em:
plot(decompose(tsMensal), xlab="Anos")
plot(decompose(tsDiario), xlab="Anos")
Realizar prospecções de curto, médio e longo prazo.
Para curto prazo, será utilizada a série temporal com dados diários (tsDiario).
Para médio e longo prazo, será utilizada a série temporal com dados mensais (tsMensal).
Separação da séries temporais em em conjuntos de treinamento e conjunto de testes.
Separação de tsDiario em conjuntos de treinamento e teste.
tsDiarioTrain <- window(tsDiario, end=(2006-0.01)) # De Jan 2002 até Dez 2005
tsDiarioTest30Days <- window(tsDiario, start=c(2006,1), end=c(2006,30)) # De 1/1/2006 a 30/1/2006
# 45 dias a partir De 1/1/2006
tsDiarioTest45Days <- window(tsDiario, start=c(2006,1), end=c(2006,45))
Separação de tsMensal em conjuntos de treinamento e teste:
tsMensalTrain <- window(tsMensal, end=c(2005, 12)) # De Jan 1992 até Dez 2005
tsMensalTest4mth <- window(tsMensal, start=2006, end=c(2006,4)) # De Jan 2006 até Mar 2006
tsMensalTest6mth <- window(tsMensal, start=2006, end=c(2006,6)) # De Jan 2006 até Jun 2006
tsMensalTest1yr <- window(tsMensal, start=2006, end=2007) # De Jan 2006 até Jan 2007
tsMensalTest2yr <- window(tsMensal, start=2006, end=(2008)) # De Jan 2006 até Jan 2008
Métricas comparativas usuais:
Diferentemente do ME, MAE e RMSE, o medidor MAPE é independente da escala.
\[M = \frac{1}{n} \sum \limits_{t=1}^{n} \left| \frac{A_t - F_t}{A_t} \right|,\]
onde \(A_t\) é o valor verdadeiro, \(F_t\) é o valor predito e \(n\) é o número de amostras temporais preditas.
Como desvantagem, o critério MAPE tem comportamento indefinido quando o valor verdadeiro \(A_t=0\) (divisão por zero).
Funções utilizadas na biblioteca forecast:
meanf()naive()snaive()rwf()Apresenta-se a seguir:
Nota:
Pacote utilizado (ver (R. J. Hyndman 2014) e (Leek 2014)):
library(forecast)
Saída: objeto forecast, contendo: * Série Original * Predições * Método utilizado * Intervalos de Predição * Resíduos
Prospecções através dos métodos simplísticos para um prazo 30 dias.
Fluxo diário de Janeiro de 2002 a Dezembro de 2005
# Dados de treinamento
plot(tsDiarioTrain, xlab="Anos", ylab="Fluxo Diário",)
title("Fluxo diário de treinamento: Jan 2002 a Dez 2005")
diasAPrever <- 30
# Média
f_mean <- meanf(tsDiarioTrain, h=diasAPrever)
plot(f_mean, xlab="Anos", ylab="Fluxo Diario", include=365)
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
# Acurácia
accuracy(f_mean, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set -3.993e-13 2462 1998 -1.64 10.48 1.065 0.7647 NA
## Test set 2.701e+03 3138 2818 11.63 12.26 1.502 0.4432 1.797
# Naïve
f_naive <- naive(tsDiarioTrain, h=diasAPrever)
plot(f_naive, xlab="Anos", ylab="Fluxo Diario", include=365)
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
# Acurácia
accuracy(f_naive, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 6.341 1681 1210 -0.3677 6.389 0.6451 -0.1089 NA
## Test set -876.950 1823 1282 -4.5074 6.186 0.6835 0.4432 1.065
# Naïve Sazonal
f_seasonal_naive <- snaive(tsDiarioTrain, h=diasAPrever)
plot(f_seasonal_naive, xlab="Anos", ylab="Fluxo Diario", include=365)
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
# Acurácia
accuracy(f_seasonal_naive, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 1579 2415 1876 7.280 9.051 1.0000 0.1346 NA
## Test set 1422 2263 1737 6.088 7.629 0.9259 0.2102 1.399
# Drift
f_drift <- rwf(tsDiarioTrain, drift = TRUE, h=diasAPrever)
plot(f_drift, xlab="Anos", ylab="Fluxo Diario", include=365)
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
# Acurácia
accuracy(f_drift, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 1.911e-13 1681 1210 -0.4006 6.391 0.6452 -0.1089 NA
## Test set -9.847e+02 1859 1287 -4.9862 6.234 0.6863 0.4333 1.088
Prospecções através dos métodos simplísticos para um prazo 4 meses.
Fluxo mensal de Janeiro de 2002 a Dezembro de 2005
# Dados de treinamento
plot(tsMensalTrain, xlab="Anos", ylab="Fluxo Mensal")
title("Fluxo mensal de treinamento: Jan 2002 a Dez 2005")
mesesAPrever <- 4
## Mean Näive N-Sazonal Drift
## Training set 22.82 4.376 7.673 4.408
## Test set 29.64 5.202 6.735 6.139
Prospecções através dos métodos simplísticos para um prazo 1 ano.
Fluxo mensal de Janeiro de 2002 a Dezembro de 2005
# Dados de treinamento
plot(tsMensalTrain, xlab="Anos", ylab="Fluxo Mensal")
title("Fluxo mensal de treinamento: Jan 2002 a Dez 2005")
mesesAPrever <- 12
## Mean Näive N-Sazonal Drift
## Training set 22.82 4.376 7.673 4.408
## Test set 34.45 5.524 7.163 4.601
diasAPrever <- 30
reg <- tslm(tsDiarioTrain ~ trend + season)
regfcast <- forecast(reg, h=diasAPrever)
plot(regfcast, xlab="Anos", ylab="Fluxo Diario", include=365)
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
accuracy(regfcast, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 9.456e-14 1263 985.7 -0.4544 5.26 0.5255 0.2678 NA
## Test set 7.235e+00 1769 1394.2 -0.5195 6.43 0.7432 0.3949 1.041
mesesAPrever <- 12
reg <- tslm(tsMensalTrain ~ trend+season)
regfcast <- forecast(reg, h=mesesAPrever)
accuracy(regfcast, tsMensalTest1yr)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set -1.754e-13 26528 21375 -0.3482 4.503 0.5763 0.9182 NA
## Test set 4.926e+04 55298 49262 6.6054 6.605 1.3281 0.6854 1.27
ARIMA (auto regressive integration moving average)
Dado no instante \(t\) de uma série temporal é dado pelo valor esperado da variável aleatória acrescida do ruído branco no instante \(t\) e a soma ponderada do ruído branco em instantes passados.
O número de instantes passados considerados é dado pela ordem do modelo.
plot(tsMensalTrain, xlab="Anos", ylab="Fluxo Mensal")
movAvg <- ma(tsMensalTrain, order=3)
lines(movAvg, col="red")
Dado no instante \(t\) de uma série temporal é expresso como a média ponderada dos dados em instantes passados acrescida de ruído branco.
O número de instantes passados considerados é dado pela ordem do modelo.
ARMA: autoregressive moving-average - combinação de ambos
ARIMA: ARMA com um passo de diferenciação
diasAPrever <- 30
Modelo:
arima_model_30days <- auto.arima(tsDiarioTrain)
## Warning: Unable to fit final model using maximum likelihood. AIC value
## approximated
Predição:
fcast_arima_30days <- forecast(arima_model_30days, h=diasAPrever)
plot(fcast_arima_30days, xlab="Anos", ylab="Fluxo Diário")
lines(tsDiarioTest30Days, col="red")
Acurácia:
accuracy(fcast_arima_30days, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 1.499 1122 901.4 -0.3162 4.745 0.4805 -0.01943 NA
## Test set -1182.930 1886 1563.8 -5.7830 7.367 0.8336 0.54952 1.103
mesesAPrever <- 4
Modelo:
arima_model_mensal <- auto.arima(tsMensalTrain)
Predição:
fcast_arima_4mth <- forecast(arima_model_mensal, h=mesesAPrever)
plot(fcast_arima_4mth, xlab="Anos", ylab="Fluxo Mensal")
lines(tsMensalTest4mth, col="red")
Acurácia:
accuracy(fcast_arima_4mth, tsMensalTest4mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 145 10236 7610 -0.0156 1.595 0.2052 -0.005073 NA
## Test set 2173 10234 8719 0.2861 1.276 0.2351 -0.511317 0.1839
mesesAPrever <- 6
Predição:
fcast_arima_6mth <- forecast(arima_model_mensal, h=mesesAPrever)
plot(fcast_arima_6mth, xlab="Anos", ylab="Fluxo Mensal")
lines(tsMensalTest6mth, col="red")
Acurácia:
accuracy(fcast_arima_6mth, tsMensalTest6mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 145 10236 7610 -0.0156 1.595 0.2052 -0.005073 NA
## Test set 3437 9902 8148 0.4719 1.181 0.2197 -0.352187 0.2011
mesesAPrever <- 12
Predição:
fcast_arima_1yr <- forecast(arima_model_mensal, h=mesesAPrever)
plot(fcast_arima_1yr)
lines(tsMensalTest1yr, col="red")
Acurácia:
accuracy(fcast_arima_1yr, tsMensalTest1yr)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 145 10236 7610 -0.0156 1.595 0.2052 -0.005073 NA
## Test set 22409 31001 24765 2.9237 3.278 0.6677 0.697780 0.7174
Algo sobre.
ets() sem parâmetros determina automaticamente.
Ver (R. J. Hyndman and Athanasopoulos 2013). O autor possui um livro exclusivamente sobre o assunto em (R. Hyndman et al. 2008).
diasAPrever <- 30
Modelo:
etsDiario <- ets(tsDiarioTrain)
## Warning: I can't handle data with frequency greater than 24. Seasonality
## will be ignored. Try stlf() if you need seasonal forecasts.
Prospecção:
fcastDiario30days <- forecast(etsDiario, h=diasAPrever)
Comparar predição com valores reais do conjunto de teste:
plot(fcastDiario30days, xlab="Anos", ylab="Fluxo Mensal");
lines(tsDiarioTest30Days, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
Acurácia:
accuracy(fcastDiario30days, tsDiarioTest30Days)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 87.87 1489 1265 -0.1499 6.7 0.6742 0.3239 NA
## Test set -676.63 1736 1252 -3.6038 6.0 0.6672 0.4432 1.013
mesesAPrever <- 6
Modelo:
etsMensal <- ets(tsMensalTrain)
Prospecção:
fcastMensal6mth <- forecast(etsMensal, h=mesesAPrever)
Comparar predição com valores reais do conjunto de teste:
plot(fcastMensal6mth, xlab="Anos", ylab="Fluxo Mensal");
lines(tsMensalTest6mth, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
Acurácia:
accuracy(fcastMensal6mth, tsMensalTest6mth)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 910 8952 6764 0.1729 1.438 0.1824 -0.005476 NA
## Test set 4511 10353 10213 0.6550 1.495 0.2753 0.152408 0.1901
mesesAPrever <- 12
Prospecção:
fcastMensal1yr <- forecast(etsMensal, h=mesesAPrever)
Comparar predição com valores reais do conjunto de teste:
plot(fcastMensal1yr);
lines(tsMensalTest1yr, col="red")
legend("topleft",legend=c("Real"),col=2,lty=1)
Acurácia:
accuracy(fcastMensal1yr, tsMensalTest1yr)
## ME RMSE MAE MPE MAPE MASE ACF1 Theil's U
## Training set 910 8952 6764 0.1729 1.438 0.1824 -0.005476 NA
## Test set 21648 29250 24499 2.8481 3.268 0.6605 0.789771 0.6718
Hyndman, Rob J. 2014. “Forecasting Time Series Using R.” http://robjhyndman.com/talks/MelbourneRUG.pdf.
Hyndman, Rob J, and George Athanasopoulos. 2013. Forecasting: principles and Practice. OTexts.
Hyndman, Rob, Anne B. Koehler, J. Keith Ord, and Ralph D. Snyder. 2008. Forecasting with Exponential Smoothing: The State Space Approach (Springer Series in Statistics). 2008th ed. Springer. http://amazon.com/o/ASIN/3540719164/.
Leek, Jeffrey. 2014. “Practical Machine Learning - Lecture 27 - Forecasting.” Johns Hopkins Bloomberg School of Public Health. https://d396qusza40orc.cloudfront.net/predmachlearn/027forecasting.pdf.